package com.starlink.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.hutool.core.convert.Convert;
import com.starlink.common.PageInfoTwo;
import com.starlink.common.exception.BusinessException;
import com.starlink.common.utils.AssertUtil;
import com.starlink.model.domain.MallBooksCategoryDO;
import com.starlink.model.dtomapper.MallCategoryDtoMapper;
import com.starlink.model.domain.MallCategoryDO;
import com.starlink.mapper.MallCategoryMapper;
import com.starlink.model.request.MallCategoryRequest;
import com.starlink.model.util.MallCategoryConvert;
import com.starlink.service.MallBooksCategoryService;
import com.starlink.service.MallCategoryService;
import com.starlink.model.vo.MallCategoryVO;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.starlink.utils.IDUtils.getId;

/**
 * @author zhanghong
 */
@Service
public class MallCategoryServiceImpl extends ServiceImpl<MallCategoryMapper, MallCategoryDO> implements MallCategoryService {
    @Autowired
    private MallCategoryMapper mallCategoryMapper;
    @Autowired
    private MallBooksCategoryService booksCategoryService;

    @Override
    public MallCategoryVO getByKey(long id) {
        MallCategoryVO mallCategoryVO = MallCategoryDtoMapper.INSTANCE.do2VO(getById(id));
        return mallCategoryVO;
    }

    @Override
    public PageInfoTwo<MallCategoryVO> pageQuery(MallCategoryRequest request) {
        long count = mallCategoryMapper.pageCount(request);
        List<MallCategoryDO> list = mallCategoryMapper.pageQuery(request, request.getPageSize(), request.fetchOffSet());
        List<MallCategoryVO> mallCategoryVOList = MallCategoryConvert.buildMallCategoryVoList(list);
        return new PageInfoTwo(request.getPageNum(), request.getPageSize(), mallCategoryVOList, count);
    }

    @Override
    public List<MallCategoryVO> listQuery(MallCategoryRequest request) {
        List<MallCategoryDO> list = mallCategoryMapper.selectDOList(MallCategoryDtoMapper.INSTANCE.request2DO(request));
        List<MallCategoryVO> mallCategoryVOS = MallCategoryConvert.buildMallCategoryVoList(list);
        return mallCategoryVOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(MallCategoryRequest request) {
        request.setId(getId());
        save(MallCategoryDtoMapper.INSTANCE.request2DO(request));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByKey(MallCategoryRequest request) {
        AssertUtil.assertNotNull(request.getId(), "id不能为空");
        saveOrUpdate(MallCategoryDtoMapper.INSTANCE.request2DO(request));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteDOById(Long ids) {
        String[] idArray = Convert.toStrArray(ids);
        List<MallCategoryDO> list = this.lambdaQuery()
                .in(MallCategoryDO::getId, idArray)
                .or()
                .in(MallCategoryDO::getParentId,idArray)
                .list();
        List<Long> collect = list.stream().map(MallCategoryDO::getId).collect(Collectors.toList());
        List<MallBooksCategoryDO> booksCategoryDOS = booksCategoryService.lambdaQuery()
                .in(MallBooksCategoryDO::getMallCategoryId, collect)
                .list();
        if (CollectionUtils.isNotEmpty(booksCategoryDOS)){
            throw new BusinessException("该分类下已有书籍绑定,暂不能删除!");
        }
        mallCategoryMapper.deleteDOByIds(idArray);
        return true;
    }

    @Override
    public List<MallCategoryVO> booksCategory() {
        List<MallCategoryDO> mallCategoryDOS = mallCategoryMapper.selectDOList(new MallCategoryDO());
        List<MallCategoryVO> mallCategoryVOS = MallCategoryConvert.buildMallCategoryVoList(mallCategoryDOS);

        if (ObjectUtils.isEmpty(mallCategoryVOS)) {
            return new ArrayList<>();
        }

        // 使用流按照 parentId 进行分组，区分空的 parentId 和非空的 parentId
        Map<Boolean, List<MallCategoryVO>> groupedByParentId = mallCategoryVOS.stream()
                .collect(Collectors.partitioningBy(category -> category.getParentId() == null));

        List<MallCategoryVO> parents = groupedByParentId.get(true);
        List<MallCategoryVO> children = groupedByParentId.get(false);

        // 如果存在父分类，为每个父分类设置其子分类
        if (parents != null) {
            parents.forEach(parent -> {
                Long parentId = parent.getId();
                List<MallCategoryVO> childrens = children.stream()
                        .filter(category -> Objects.equals(category.getParentId(), parentId))
                        .collect(Collectors.toList());
                parent.setChildren(childrens);
            });
        }

        return parents != null ? parents : new ArrayList<>();
    }

}